#include "tetra.hh"

char Tetra::tetraMas[][8] = { { 2, 0,
                                2, 1,
                                2, 2,
                                2, 3 }, // I
                              { 2, 0,
                                2, 1,
                                2, 2,
                                1, 2 }, // J
                              { 1, 0,
                                1, 1,
                                1, 2,
                                2, 2 }, // L
                              { 1, 1,
                                2, 1,
                                1, 2,
                                2, 2 }, // O
                              { 1, 2,
                                2, 2,
                                2, 1,
                                3, 1 }, // S
                              { 0, 2,
                                1, 1,
                                1, 2,
                                2, 2 }, // T
                              { 0, 1,
                                1, 1,
                                1, 2,
                                2, 2 } // Z
                            };

/**
* =============================================================================
* Конструктор класса Tetra
* =============================================================================
* @param typeSize
*  Размер массива для хранения тетры
* @param type
*  Тип тетры, которая будет создана
* @param color
*  Цвет тетры
* =============================================================================
*/
Tetra::Tetra(uint typeSize, int type, char color) {
    TypeSize() = typeSize;

    // TODO возможен segfault из-за неверной работы с указателям
    this->type = new char * [TypeSize()];
    for (uint i = 0; i < TypeSize(); i++) {
        this->type[i] = new char[TypeSize()];
    }

    selectTetra(type, color);
}

Tetra::~Tetra() {
    // Возвращаем память массива type в кучу
    for (uint i = 0; i < TypeSize(); i++) {
        delete [] type[i];
    }
    delete type;
}

/**
* =============================================================================
* Поворот тетры
* =============================================================================
* @param clockwise
*  Сторона, в которую будет выполнен поворот
*  true - по часовой стрелке, false - против
* =============================================================================
*/
void Tetra::rotate(bool clockwise) {
    // Создаём буфферный массив
    //char (&buff)[4][4] = (char (&)[4][4]) *new char [4*4];
    char ** buff = new char * [TypeSize()];
    for (uint i = 0; i < TypeSize(); i++) {
        buff[i] = new char[TypeSize()];
    }
    // копируем в него основной
    for(uint i = 0; i < TypeSize(); i++) {
        memcpy(buff[i], type[i], sizeof(type[i]));
    }

    /*for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            buff[i][j]=type[i][j];
        }
    }*/
    if(clockwise) {// По часовой стрелке
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                type[i][j]=buff[3-j][i];
            }
        }
    } else { // Против часовой стрелки
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                type[i][j]=buff[j][3-i];
               }
        }
    }
    // Возвращаем память массива buff в кучу
    for(uint i = 0; i < TypeSize(); i++) {
        delete [] buff[i];
    }
    delete [] buff;
}

/**
* =============================================================================
* Выбор тетры и её цвета
* =============================================================================
* @param type
*  Тип тетры
* @param color
*  Цвет тетры
* =============================================================================
*/
bool Tetra::selectTetra(int type, char color) {
    if (type < 0 || type > 6) {
        return false;
    }
    // Обнуляем форму текущей тетры
    for (int i=0; i<4; i++)
        for (int j=0;j<4;j++)
            this->type[i][j] = 0;
    // И заполняем её нужной
    for(int j = 0; j < 8; j+=2) {
        this->type[int(tetraMas[type][j])][int(tetraMas[type][j+1])] = color;
    }
    return true;
}
